﻿//Copyright 2011 University of Southampton 
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Diagnostics;


namespace SharePointEntityProject.EntityEditorLib
{
    public class ContentTypeManagmentLib: IDisposable
    {


        private string SITE_URL;
        private SPSite site;
        private SPWeb web;

        public ContentTypeManagmentLib(string siteUrl)
        {
            SITE_URL = siteUrl;
            site = new SPSite(SITE_URL);
            web = site.OpenWeb();
        }


        public void Dispose()
        {
            this.web.Dispose();
            this.site.Dispose();
        }



        public SPContentType GetOrCreateContentType(string groupName, string contentTypeName,
            string partentContentTypeName, string description
            )
        {
            //Lookup up parent
            SPContentType parent = web.AvailableContentTypes[partentContentTypeName];
            Debug.Assert(parent != null);
            return GetOrCreateContentType(groupName, contentTypeName, parent, description);
        }


        private SPContentType GetOrCreateContentType(string grp, string contentTypeName,
            SPContentType parentContentType, string description)
        {
            Debug.WriteLine(String.Format("Looking up CT: {0}", contentTypeName));
            //see if it exists
            SPContentType existingCT = web.ContentTypes[contentTypeName];//null if not exists
            if (existingCT != null)
            {
                //Content Type exists
                if (!existingCT.Parent.Id.Equals(parentContentType.Id))
                {//Cannot change content type parent

                    throw new Exceptions.ChangeParentTypeException();
                }
            }
            else
            {
                //Create it
                existingCT = new SPContentType(parentContentType, web.ContentTypes, contentTypeName);
                //add it
                web.ContentTypes.Add(existingCT);
                existingCT.Update(true);
            }


            if (!existingCT.Description.Equals(description))
            {
                existingCT.Description = description;
                Debug.WriteLine("Updating CT description");
            }
            if (!existingCT.Group.Equals(grp))
            {
                existingCT.Group = grp;
                Debug.WriteLine("Updating CT group Name" + grp);
            }

            existingCT.Update(true);
            return existingCT;


        }

        internal List<SPContentType> GetCTListByGroup(string groupName)
        {
            List<SPContentType> AllEntities = new List<SPContentType>();
            foreach (SPContentType curCT in web.AvailableContentTypes)
            {
                //only select by our group
                if (curCT.Group.Equals(groupName))
                {
                    AllEntities.Add(curCT);
                }
            }

            return AllEntities;
            
        }

        private SPContentType GetContentTypeByID(string id)
        {
            SPContentTypeId cTypeId = new SPContentTypeId(id);

            SPContentType cT = this.web.ContentTypes[cTypeId];
            return cT;
        }

        private SPField GetFieldByName(string name)
        {


            SPField cField = this.web.AvailableFields[name];
            return cField;
        }

        private SPField GetFieldByID(string idStr)
        {
            Guid id = new Guid(idStr);

            SPField cField = this.web.AvailableFields[id];
            return cField;
        }



        private SPContentType GetContentTypeByName(string name)
        {


            SPContentType cT = this.web.ContentTypes[name];
            return cT;
        }
        
        //Get the actual Fields 
        internal Dictionary<string, SPField> GetEntityFields(string entityID)
        {
            Dictionary<string, SPField> results = new Dictionary<string, SPField>();
            //get the CT
            SPContentType cType = GetContentTypeByID(entityID);

           // get the fields
            var t= web.Fields.List;
            //web.Fields.
            foreach (SPField field in cType.Fields)
            {
                Debug.WriteLine(field.Title);
                results[field.Id.ToString()] = field;
            }

            

            return results;
        }


        internal List<SPFieldLink> GetEntityFieldLinks(string entityID)
        {
            List<SPFieldLink> results = new List<SPFieldLink>();
            //get the CT
            SPContentType cType = GetContentTypeByID(entityID);

           // get the fields
            var t= web.Fields.List;
            //web.Fields.
             

            foreach (SPFieldLink fieldLink in cType.FieldLinks)
            {
                Debug.WriteLine(fieldLink.Name);
                //results.Add(field);
                results.Add(fieldLink);
            }

            return results;
        }


        internal void AddFieldToContentType(string contentTypeId, string fieldId)
        {
            SPContentType cType = GetContentTypeByID(contentTypeId);

            //All fields must be at site level
            SPField cField = GetFieldByID(fieldId);
            
            SPFieldLink newSPFieldLink = new SPFieldLink(cField);
            
            //add it
            
            cType.FieldLinks.Add(newSPFieldLink);

          
            cType.Update(true);
        }

        internal List<SPField> GetAllFieldsOnSite()
        {
            List<SPField> results = new List<SPField>();
           

            foreach (SPField field in web.AvailableFields)
            {
               

                Debug.WriteLine(field.Title);
                results.Add(field);
            }

            return results;

        }

        internal List<SPContentType> GetCTListByList(string p)
        {
            throw new NotImplementedException();
        }
    }
}
